<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2018/6/19
 * Time: 14:30
 */

namespace app\common\pay;

use Alipay\aop\request\AlipayTradeFastpayRefundQueryRequest;
use \Alipay\aop\request\AlipayTradeCloseRequest;
use app\common\lib\Orders as OrdersLib;
use \Alipay\aop\AopClient;
use \Alipay\aop\request\AlipayTradeQueryRequest as AppPayQueryRequest;
use Alipay\aop\request\AlipayTradeRefundRequest;

/**
 * @title 支付宝支付相关接口
 * @desc 支付宝支付
 * @url
 * @version 1.1.1
 * Class Ali
 * @package app\api\controller\v2
 */
class Ali
{
    /**
     * 支付方式模型名称
     * @var array
     */
    private $payTypeModelName = [
        'APP' => '\Alipay\aop\request\AlipayTradeAppPayRequest',
        'WAP' => '\Alipay\aop\request\AlipayTradeWapPayRequest',
    ];

    /**
     * 实例化支付模型
     * @param $payType string
     * @return mixed
     */
    protected function getModel(string $payType)
    {
        $className = $this->payTypeModelName[$payType];

        return new $className();
    }

    /**
     * 支付宝支付
     * @param $goods_type //1=>虚拟,2=>实体
     * @param $body string 商品名称
     * @param $out_trade_no string 订单号
     * @param $total_amount float 订单价格
     * @param string $payType 支付方式
     * @param string $return_url WAP支付时的前台支付完成回跳地址
     * @return string
     * @throws \Exception
     */
    public function pay($body, $out_trade_no, $total_amount, $payType = 'APP', string $return_url = '', $goods_type = 1)
    {
        $aop = new AopClient();
        //获取订单支付账号配置
        $accountConfig = \app\common\cachemodel\OrdersLib::getOrderAccountType($out_trade_no, 1);
        $aliConfig = OrdersLib::getPayConfig('ali', $accountConfig['account']);

        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['app_id'];
        $aop->rsaPrivateKey = $aliConfig['merchant_private_key'];
        $aop->format = "json";
        $aop->postCharset = "UTF-8";
        $aop->signType = "RSA2";
        $aop->apiVersion = '1.0';
        $aop->alipayrsaPublicKey = $aliConfig['alipay_public_key'];

        $request = $this->getModel($payType);

        $arr['body'] = $body;
        $arr['subject'] = $body;
        $arr['out_trade_no'] = $out_trade_no;
        $arr['timeout_express'] = '1d';


        $arr['total_amount'] = "$total_amount";
//        $arr['total_amount'] = 0.01;
        $arr['product_code'] = $payType == 'APP' ? 'QUICK_MSECURITY_PAY' : 'QUICK_WAP_WAY';

        $json = json_encode($arr);

//        \think\Log::write('支付宝支付回调地址:商品类型:'.$goods_type.';回调地址'.json_encode($aliConfig,true),'log',true);

        $request->setNotifyUrl($aliConfig['notify_url' . $goods_type]);

        $request->setBizContent($json);

        if ($payType == 'APP')
        {
            // APP支付
            $response = $aop->sdkExecute($request);
        } else
        {
            $request->setReturnUrl($return_url);
            // 手机网页支付
            $response = $aop->pageExecute($request);
        }
//        Log::write('AliPay_Response:'. json_encode($response),'log',true);
        return $response;
    }

    /**
     * 支付宝支付 V2
     * @param $body string 商品名称
     * @param $out_trade_no string 订单号
     * @param $total_amount float 订单价格
     * @param string $payType 支付方式
     * @param string $return_url WAP支付时的前台支付完成回跳地址
     * @return string
     * @throws \Exception
     */
    public function payV2($body,string $out_trade_no, $total_amount, $payType = 'APP', string $return_url = '', $aliConfig = [])
    {
        $aop = new AopClient();
        //获取订单支付账号配置
        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['app_id'];
        $aop->rsaPrivateKey = $aliConfig['merchant_private_key'];
        $aop->format = "json";
        $aop->postCharset = "UTF-8";
        $aop->signType = "RSA2";
        $aop->apiVersion = '1.0';
        $aop->alipayrsaPublicKey = $aliConfig['alipay_public_key'];

        $request = $this->getModel($payType);

        $arr['body'] = $body;
        $arr['subject'] = $body;
        $arr['out_trade_no'] = (string)$out_trade_no;
        $arr['timeout_express'] = '1d';


        $arr['total_amount'] = "$total_amount";
//        $arr['total_amount'] = 0.01;
        $arr['product_code'] = $payType == 'APP' ? 'QUICK_MSECURITY_PAY' : 'QUICK_WAP_WAY';

        $json = json_encode($arr);

//        \think\Log::write('支付宝支付回调地址:商品类型:'.$goods_type.';回调地址'.json_encode($aliConfig,true),'log',true);
        $request->setNotifyUrl($aliConfig['notify_url']);

        $request->setBizContent($json);

        if ($payType == 'APP')
        {
            // APP支付
            $response = $aop->sdkExecute($request);
        } else
        {
            $request->setReturnUrl($return_url);
            // 手机网页支付
            $response = $aop->pageExecute($request);
        }
//        Log::write('AliPay_Response:'. json_encode($response),'log',true);
        return $response;
    }

    /**
     * 支付宝订单查询
     * 文档地址： https://docs.open.alipay.com/api_1/alipay.trade.query/
     * @param array $data 商品数据
     * @param int $account 支付宝订单使用的商户配置id
     * @return bool|mixed|\SimpleXMLElement
     * @throws \Exception
     */
    public function query($data = [], $account = 0)
    {
        $aliConfig = OrdersLib::getPayConfig('ali', $account);
        $aop = new AopClient();
        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['app_id'];
        $aop->rsaPrivateKey = $aliConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey = $aliConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $request = new AppPayQueryRequest();

        $json = json_encode($data);
        $request->setBizContent($json);
        return $aop->execute($request);
    }

    /**
     * 支付宝：统一收单交易退款接口
     * @doc https://opendocs.alipay.com/apis/api_1/alipay.trade.refund
     * @param array $data 商品数据
     * @param int $account 支付宝订单使用的商户配置id
     * @return bool|mixed|\SimpleXMLElement|null
     * @throws \Exception
     */
    public function refund($data, $account)
    {
        $aliConfig = OrdersLib::getPayConfig('ali', $account);
        $aop = new AopClient();
        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['app_id'];
        $aop->rsaPrivateKey = $aliConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey = $aliConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $request = new AlipayTradeRefundRequest();

        $json = json_encode($data);
        $request->setBizContent($json);
        return $aop->execute($request);
    }

    /**
     * 支付宝：统一收单交易关闭接口
     * @doc https://opendocs.alipay.com/open/02e7gn
     * @throws \Exception
     */
    public function close($out_trade_no, $account)
    {
        $aliConfig = OrdersLib::getPayConfig('ali', $account);
        $aop = new AopClient ();
        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['app_id'];
        $aop->rsaPrivateKey = $aliConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey = $aliConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $object = new \stdClass();
        $object->out_trade_no = $out_trade_no;//APP订单编号
        $json = json_encode($object);
        $request = new AlipayTradeCloseRequest();
        $request->setBizContent($json);
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        return $result->$responseNode;
    }

    /**
     * 支付宝：统一收单交易退款查询 AlipayTradeFastpayRefundQueryRequest
     * @doc https://opendocs.alipay.com/apis/api_1/alipay.trade.fastpay.refund.query
     * @param array $data 商品数据
     * @param int $account 支付宝订单进行使用的商户配置id
     */
    public function refundquery($data, $account)
    {
        $aliConfig = OrdersLib::getPayConfig('ali', $account);
        $aop = new AopClient();
        $aop->gatewayUrl = $aliConfig['gatewayUrl'];
        $aop->appId = $aliConfig['app_id'];
        $aop->rsaPrivateKey = $aliConfig['merchant_private_key'];
        $aop->alipayrsaPublicKey = $aliConfig['alipay_public_key'];
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        $request = new AlipayTradeFastpayRefundQueryRequest();

        $json = json_encode($data);
        $request->setBizContent($json);
        $result = $aop->execute($request);

        return $result;
    }
}
